package com.wyp168.juc.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @ClassName LockToCASDemo
 * @Description 使用cas机制代替lock和unlock
 * @Author wyp168
 * @Date 2022/9/17 10:04
 */
public class LockToCASDemo {
    private AtomicReference<Thread> atomicReference = new AtomicReference<>();
    private Thread thread = new Thread();   //标识位

    //模拟上锁的方法
    public void lock() {
        System.out.println(Thread.currentThread().getName() + "\t >>> come in~");
        //使用cas自旋锁来代替上锁
        /**
         * 如果atomicReference 对象的引用值为null，则替换为thread，并且返回true，由于判断的时候为非，所以while判断语句块中的值为false，跳出循环
         * 如果对象引用值不为null， 则不进行替换，并且返回false，false再进行非运算时为true，所以一直循环
         */
        while (!atomicReference.compareAndSet(null, thread)) {

        }
    }

    //模式释放锁的方法
    public void unlock() {
        while (!atomicReference.compareAndSet(thread, null)) {

        }
        System.out.println(Thread.currentThread().getName() + "\t >>>> task over!");
    }

    public static void main(String[] args) {
        LockToCASDemo lock = new LockToCASDemo();
        new Thread(() -> {
            lock.lock();
            //暂停几秒钟线程，观察锁是否被B线程获取
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) {e.printStackTrace();}
            lock.unlock();
        }, "A").start();

        new Thread(() -> {
            lock.lock();

            lock.unlock();
        }, "B").start();
    }
}
